﻿// Custom Commands
//
// This example program illustrates creating a custom command.  In this case clicking a generic trigger on
// your aircraft panel writes to the DataRef controlling the pilots head position either continuously or one
// knotch at a time. We could use the existing position command: sim/view/move_right, however for illustrative
// purposes, this example uses a custom command:  BSUB/ViewPoint/MoveRight
//
// For this example to work it is necessary to create a generic trigger on the panel of your aircraft keyed
// to the command: BSUB/ViewPoint/MoveRight.
//
// Content added by BlueSideUpBob.
//
#pragma comment(lib,"ws2_32.lib")
#include "XPLMPlugin.h"
#include "XPLMDisplay.h"
#include "XPLMGraphics.h"
#include "XPLMProcessing.h"
#include "XPLMDataAccess.h"
#include "XPLMMenus.h"
#include "XPLMUtilities.h"
#include "XPWidgets.h"
#include "XPStandardWidgets.h"
#include "XPLMScenery.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "XPLMDisplay.h"
#include "XPLMGraphics.h"
#include "XPLMProcessing.h"
#include "XPLMDataAccess.h"
#include "XPLMMenus.h"
#include "XPLMUtilities.h"
#include "XPWidgets.h"
#include "XPStandardWidgets.h"
#include "XPLMCamera.h"
#include <thread>
#include "XPLMDisplay.h"
#include "XPLMGraphics.h"
#include "XPLMProcessing.h"
#include "XPLMDataAccess.h"
#include "XPLMMenus.h"
#include "XPLMUtilities.h"
#include "XPWidgets.h"
#include "XPStandardWidgets.h"
#include "XPLMCamera.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <XPLMCamera.h>
#include <algorithm>
struct CameraProperties {
	double loc[3];
	float direction[3];
	float zoom;
};
XPLMDataRef gHeadPositionXDataRef = NULL;
XPLMDataRef gHeadRainDataRef = NULL;
XPLMDataRef gHeadSnowDataRef = NULL;
XPLMDataRef gHeadSnowDataRef1 = NULL;
XPLMDataRef gHeadViewDataRef1 = NULL;

XPLMCommandRef MyCommand = NULL;
static double pointx = 0;
static double pointy = 0;
static double pointz = 0;
static void ControlMenuHandler(void*, void*);
void func();
PLUGIN_API int XPluginStart(
	char* outName,
	char* outSig,
	char* outDesc)
{
	// Plugin Info
	strcpy(outName, "CommandControl");
	strcpy(outSig, "BlueSideUpBob.Example.CommandControl");
	strcpy(outDesc, "This example illustrates creating and sending a custom command to X-Plane using a generic trigger.");
	int item = XPLMAppendMenuItem(XPLMFindPluginsMenu(), "YunXiangHang", NULL, 1);
	XPLMMenuID id = XPLMCreateMenu("Control", XPLMFindPluginsMenu(), item, ControlMenuHandler, NULL);

	XPLMAppendMenuItem(id, "Control", (void*)"Control", 1);
	
	XPLMAppendMenuItem(id, "Overcast", (void*)"Overcast", 1);
	XPLMAppendMenuItem(id, "Clear", (void*)"Clear", 1);
	XPLMAppendMenuItem(id, "Rain", (void*)"Rain", 1);
	XPLMAppendMenuItem(id, "Snow", (void*)"Snow", 1);
	XPLMAppendMenuItem(id, "RainOrSnowStop", (void*)"RainOrSnowStop", 1);

	XPLMAppendMenuItem(id, "xuyongsheng", (void*)"xuyongsheng", 1);

	//XPLMAppendMenuItemWithCommand(id1, "Toggle Flight Configuration", XPLMFindCommand("sim/weather/cloud_type[1]"));
	// Create the test command, this will move the pilots point of view 10 cm to the right.


//	gHeadPositionXDataRef = XPLMFindDataRef("sim/graphics/view/field_of_view_deg");
//	gHeadPositionXDataRef = XPLMFindDataRef("sim/graphics/view/view_type");
	
	gHeadPositionXDataRef = XPLMFindDataRef("sim/weather/cloud_type[1]");
	gHeadRainDataRef = XPLMFindDataRef("sim/weather/rain_percent");
	gHeadSnowDataRef = XPLMFindDataRef("sim/weather/temperature_sealevel_c");
	gHeadSnowDataRef1 = XPLMFindDataRef("sim/weather/temperature_tropo_c");
	
	return 1;
}



PLUGIN_API void XPluginDisable(void)
{
}

PLUGIN_API int XPluginEnable(void)
{
	return 1;
}

PLUGIN_API void XPluginReceiveMessage(
	XPLMPluginID    inFromWho,
	long            inMessage,
	void* inParam)
{
	if (inFromWho == XPLM_PLUGIN_XPLANE)
	{
		switch (inMessage)
		{
		case XPLM_MSG_PLANE_LOADED:
			XPLMCommandKeyStroke(xplm_key_tower);
			std::thread t1(func);
			t1.detach();
			break;
		}
	}
	
}
void func()
{
	
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD(1, 1);

	err = WSAStartup(wVersionRequested, &wsaData);//错误会返回WSASYSNOTREADY
	if (err != 0)
	{
		return ;
	}

	if (LOBYTE(wsaData.wVersion) != 1 ||     //低字节为主版本
		HIBYTE(wsaData.wVersion) != 1)      //高字节为副版本
	{
		WSACleanup();
		return ;
	}

	printf("server is operating!\n\n");
	//创建用于监听的套接字
	SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);//失败会返回 INVALID_SOCKET
	//printf("Failed. Error Code : %d",WSAGetLastError())//显示错误信息

	SOCKADDR_IN addrSrv;     //定义sockSrv发送和接收数据包的地址
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);

	//绑定套接字, 绑定到端口
	bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//会返回一个SOCKET_ERROR
	//将套接字设为监听模式， 准备接收客户请求


	SOCKADDR_IN addrClient;   //用来接收客户端的地址信息
	int len = sizeof(SOCKADDR);
	char recvBuf[1];    //收
   //发
	char tempBuf[1];    //存储中间信息数据


	while (1)
	{

		//等待并数据
		recvfrom(sockSrv, recvBuf, 1, 0, (SOCKADDR*)&addrClient, &len);
		continue;
		if ('1' == recvBuf[0])
		{

			XPLMSetDatai(gHeadPositionXDataRef, 4);
			XPLMSetDataf(gHeadRainDataRef, 0);
			XPLMSetDataf(gHeadSnowDataRef1, 23);
			XPLMSetDataf(gHeadSnowDataRef, 23);
		}
		else if ('2' == recvBuf[0])
		{
			XPLMSetDatai(gHeadPositionXDataRef, 0);
			XPLMSetDataf(gHeadSnowDataRef1, 23);
			XPLMSetDataf(gHeadSnowDataRef, 23);
		}
		else if ('3' == recvBuf[0])
		{
			XPLMSetDatai(gHeadPositionXDataRef, 4);
			XPLMSetDataf(gHeadRainDataRef, 0.8);
			XPLMSetDataf(gHeadSnowDataRef1, 23);
			XPLMSetDataf(gHeadSnowDataRef, 23);
		}
		else if ('4' == recvBuf[0])
		{
			//XPLMSetDatai(gHeadPositionXDataRef, 0);
			XPLMSetDataf(gHeadRainDataRef, 0);
			XPLMSetDataf(gHeadSnowDataRef1, 23);
			XPLMSetDataf(gHeadSnowDataRef, 23);
		}
		else if ('5' == recvBuf[0])
		{
			XPLMSetDatai(gHeadPositionXDataRef, 4);
			XPLMSetDataf(gHeadRainDataRef, 0.8);
			XPLMSetDataf(gHeadSnowDataRef1, -23);
			XPLMSetDataf(gHeadSnowDataRef, -23);
		}
		//else if ('6' == recvBuf[0])
		//{
		//	float FloatValue[3];
		//	double DoubleValue[3];
		//	char	buffer[512];
		//	int Item;


		//	//// This gets the lat/lon/alt from the widget text fields
		//	//for (Item = 0; Item < 3; Item++)
		//	//{
		//	//	XPGetWidgetDescriptor(Position2Edit[Item], buffer, 512);
		//	//	FloatValue[Item] = atof(buffer);
		//	//}
		//	FloatValue[0] = 22;
		//	FloatValue[1] = 113;
		//	FloatValue[2] = 22;
		//	/// Lat, Lon, Alt, X, Y, Z
		//	XPLMWorldToLocal(FloatValue[0], FloatValue[1], FloatValue[2] / 3.28, &DoubleValue[0], &DoubleValue[1], &DoubleValue[2]);
		//	pointx = DoubleValue[0];
		//	pointy = DoubleValue[1];
		//	pointz = DoubleValue[2];

		//	MyHotKeyCallback(NULL);
		//}
		//else if('7'==recvBuf[0])
		//{
		//	XPLMCommandKeyStroke(73);
		//}
		printf("%s\n", recvBuf);

		//发送数据
		printf("Please input data: \n");


	}
	closesocket(sockSrv);
	WSACleanup();

}
typedef enum
{
	XPC_VIEW_FORWARDS = 73,//机舱视角
	XPC_VIEW_DOWN,//机舱视角
	XPC_VIEW_LEFT,//机舱视角
	XPC_VIEW_RIGHT,//机舱视角
	XPC_VIEW_BACK,//机舱视角
	XPC_VIEW_TOWER,//塔台
	XPC_VIEW_RUNWAY,//跑道
	XPC_VIEW_CHASE,//追逐
	XPC_VIEW_FOLLOW,//环绕
	XPC_VIEW_FOLLOWWITHPANEL,//---
	XPC_VIEW_SPOT,//静止视角
	XPC_VIEW_FULLSCREENWITHHUD,//--
	XPC_VIEW_FULLSCREENNOHUD,//--
} VIEW_TYPE;
void ControlMenuHandler(void* mRef, void* iRef)
{

	//XPLMSetDataf(gHeadPositionXDataRef, (float)103);
   //XPLMSetDatai(gHeadPositionXDataRef, 73);
	if (!strcmp((const char*)iRef, "Control"))
	{
		//XPLMCommandKeyStroke(73);
	}
	else if (!strcmp((const char*)iRef, "Overcast"))
	{
		XPLMSetDatai(gHeadPositionXDataRef, 4);
		XPLMSetDataf(gHeadRainDataRef, 0);
		XPLMSetDataf(gHeadSnowDataRef1, 23);
		XPLMSetDataf(gHeadSnowDataRef, 23);
	}
	else if (!strcmp((const char*)iRef, "Clear"))
	{
		XPLMSetDatai(gHeadPositionXDataRef, 0);
		XPLMSetDataf(gHeadSnowDataRef1, 23);
		XPLMSetDataf(gHeadSnowDataRef, 23);
	}
	else if (!strcmp((const char*)iRef, "Rain"))
	{
		XPLMSetDatai(gHeadPositionXDataRef, 4);
		XPLMSetDataf(gHeadRainDataRef, 0.8);
		XPLMSetDataf(gHeadSnowDataRef1, 23);
		XPLMSetDataf(gHeadSnowDataRef, 23);
	}
	else if (!strcmp((const char*)iRef, "RainOrSnowStop"))
	{
		//XPLMSetDatai(gHeadPositionXDataRef, 0);
		XPLMSetDataf(gHeadRainDataRef, 0);
		XPLMSetDataf(gHeadSnowDataRef1, 23);
		XPLMSetDataf(gHeadSnowDataRef, 23);

	}
	else if (!strcmp((const char*)iRef, "Snow"))
	{
		XPLMSetDatai(gHeadPositionXDataRef, 4);
		XPLMSetDataf(gHeadRainDataRef, 0.8);
		XPLMSetDataf(gHeadSnowDataRef1, -23);
		XPLMSetDataf(gHeadSnowDataRef, -23);
	}

}


